Due to increasing complexity of modern software systems, the likelihood of making errors during a software design phase has increased exponentially. While some of these errors might be detected during testing phase, it is much more cost effective to detect these errors early during design phase. For this reason, formal specification and analysis tools are increasingly being deployed to improve the quality of software design.
Among the various kinds of testing usually performed during the software development cycle, unit testing applies to the individual components of a software system. In principle, unit testing plays an important role in ensuring overall software quality since its role is precisely to detect errors in the component's logic, check all corner cases, and provide complete code coverage. Yet, in practice, unit testing is so hard and expensive to perform that it is rarely done properly. Indeed, in order to be able to execute and test a component in isolation, one needs to write test driver/harness code to simulate the environment of the component. More code is needed to test functional correctness, for instance using assertions checking the component's outputs. Since writing all of this testing code manually is expensive, unit testing is often either performed very poorly or skipped altogether. Moreover, subsequent phases of testing, such as feature, integration and system testing, are meant to test the overall correctness of the entire system viewed as a black-box, not to check the corner cases where bugs causing reliability issues are typically hidden. As a consequence, many software bugs that should have been caught during unit testing remain undetected until field deployment.
Successful software development and implementation requires various levels of software testing. In some instances, software testing involves a developer, tester, or other worker manually analyzing software code and manually generating test cases for each functional aspect of the software to be tested. In other instances, the unit testing is done partially automated partially manually or fully automated by a dedicated apparatus an testing software.
As referred to herein, a test case refers to the set of parameters necessary for unit testing the proper operation of a functional aspect in a reasonable percentage of possible scenarios. The developer, tester, or other worker must then write test code for each function to “unit test” the software. As used herein, unit testing refers to validating that a particular functional aspect for a particular unit of software operates properly under certain relatively predictable conditions. Because the test cases are designed to test the proper operation of a functional aspect in a reasonable percentage of predictable conditions, there may be scenarios that arise during further testing or post-implementation scenarios wherein the unit of software “regresses” (e.g., fails to perform properly wherein it previously performed properly). In these cases of regression, prior unit testing aids developers or other workers by establishing a threshold or baseline. This baseline indicates that the regression was caused by parameters outside the baseline. This knowledge focuses remedial efforts and additional testing of the software.
However, the development of test cases, test code, the running of unit tests, and the interpretation of unit tests is a time consuming process. In many cases, developers do not have the time or the motivation to properly perform all of these unit testing procedures. In some cases, this type of testing is passed on to testers. However, in some cases, testers are not as technically savvy regarding the software language in which the software code is written, and thus, are not always able to properly perform unit testing. Because of these and other challenges and problems to performing basic unit testing, it often goes undone or is performed incompletely or inadequately.